﻿using System;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using static MouseClicker;

public class MouseClickTool : Form
{
    // UI 控件
    private Label intervalLabel, hotkeyLabel, hotkeyLabel2, clickCountLabel, progressLabel;
    private ComboBox hotkeyComboBox, buttonComboBox;
    private TextBox intervalTextBox, clickCountTextBox;
    private ProgressBar progressBar;
    private Button startButton;

    // 鼠标点击器对象，用于处理点击逻辑
    private MouseClicker clicker;

    // 快捷键相关变量
    private Keys startStopHotkey = Keys.F2;
    private int hotkeyId = 1;
    private NotifyIcon trayIcon; // 系统托盘图标

    // 全局鼠标和快捷键控制
    [DllImport("user32.dll")]
    private static extern bool SetProcessDPIAware();

    [DllImport("user32.dll", SetLastError = true)]
    private static extern bool RegisterHotKey(IntPtr hWnd, int id, uint fsModifiers, uint vk);

    [DllImport("user32.dll", SetLastError = true)]
    private static extern bool UnregisterHotKey(IntPtr hWnd, int id);

    public MouseClickTool()
    {
        // 创建 UI 控件
        Text = "MouseClickTool";
        BackColor = Color.GhostWhite;
        StartPosition = FormStartPosition.CenterScreen;

        // 初始化 UI 组件
        CreateControls();
        ArrangeLayout();

        // 创建系统托盘图标
        CreateTrayIcon();

        // 初始化鼠标点击器对象，使用默认值
        clicker = new MouseClicker(1000, 1000, UpdateProgress);

        // 注册全局快捷键（默认 F2）
        RegisterHotKey();

        // 设置窗口关闭事件
        FormClosing += (__, _) => Application.Exit();
    }

    // 初始化 UI 组件
    private void CreateControls()
    {
        intervalLabel = new Label { Text = "间隔(ms):", AutoSize = true };
        intervalTextBox = new TextBox { Text = "100", Width = 50 };

        clickCountLabel = new Label { Text = "点击次数:", AutoSize = true };
        clickCountTextBox = new TextBox { Text = "1000", Width = 50 };

        hotkeyLabel = new Label { Text = "快捷键:", AutoSize = true };
        hotkeyComboBox = new ComboBox { DropDownStyle = ComboBoxStyle.DropDownList };
        for (int i = 1; i < 13; i++)
        {
            hotkeyComboBox.Items.Add("F" + i);
        }
        hotkeyComboBox.SelectedIndex = 1; // 默认选择 F2
        hotkeyComboBox.SelectedIndexChanged += HotkeyComboBox_SelectedIndexChanged;

        buttonComboBox = new ComboBox { DropDownStyle = ComboBoxStyle.DropDownList };
        hotkeyLabel2 = new Label { Text = "按键键值:", AutoSize = true };
        buttonComboBox.Items.AddRange(new[] { "左键", "右键" });
        buttonComboBox.SelectedIndex = 0;

        progressLabel = new Label { Text = "进度: 0/1000", AutoSize = true };

        progressBar = new ProgressBar { Minimum = 0, Maximum = 1000, Width = 200 };

        startButton = new Button { Text = "开始", AutoSize = true };
        startButton.Click += StartButtonClick;
    }

    // 布局控件
    private void ArrangeLayout()
    {
        int padding = 5;  // 控件之间的间距
        int labelWidth = 60;  // 标签宽度
        int inputWidth = 80;  // 输入框和下拉框的宽度
        int buttonWidth = 90;  // 开始按钮的宽度
        int progressWidth = 100;  // 进度条宽度
        int controlHeight = 25;  // 控件高度设置为25，保证紧凑布局

        // 控件起始位置
        int leftColumnX = padding;  // 左列X坐标
        int rightColumnX = leftColumnX + labelWidth + inputWidth + padding * 2;  // 右列X坐标
        int currentY = padding;  // 当前Y坐标，初始为padding

        // 第一行：左列：间隔（毫秒），右列：点击次数
        intervalLabel.SetBounds(leftColumnX, currentY, labelWidth, controlHeight);
        intervalTextBox.SetBounds(intervalLabel.Right + padding, currentY, inputWidth, controlHeight);
        clickCountLabel.SetBounds(rightColumnX, currentY, labelWidth, controlHeight);
        clickCountTextBox.SetBounds(clickCountLabel.Right + padding, currentY, inputWidth, controlHeight);

        // 调整Y坐标，用于下一行控件
        currentY += controlHeight + padding;

        // 第二行：左列：快捷键，右列：键值选择框
        hotkeyLabel.SetBounds(leftColumnX, currentY, labelWidth, controlHeight);
        hotkeyComboBox.SetBounds(hotkeyLabel.Right + padding, currentY, inputWidth, controlHeight);
        hotkeyLabel2.SetBounds(rightColumnX, currentY, labelWidth, controlHeight);
        buttonComboBox.SetBounds(hotkeyLabel2.Right + padding, currentY, inputWidth, controlHeight);

        // 调整Y坐标，用于下一行控件
        currentY += controlHeight + padding;

        // 第三行：左列放置进度标签，右列放置开始按钮
        progressLabel.SetBounds(leftColumnX, currentY, labelWidth, controlHeight);  // 左侧：进度标签
        startButton.SetBounds(rightColumnX, currentY, buttonWidth, controlHeight);  // 右侧：开始按钮

        // 调整Y坐标，用于放置进度条
        currentY += controlHeight + padding;

        // 进度条独占一行，放置在最底部
        progressBar.SetBounds(leftColumnX, currentY, progressWidth + labelWidth + inputWidth + padding * 2, controlHeight);

        // 添加所有控件到窗体中
        Controls.AddRange(new Control[] {
        intervalLabel, intervalTextBox, clickCountLabel, clickCountTextBox,
        hotkeyLabel, hotkeyLabel2, hotkeyComboBox, buttonComboBox, startButton,
        progressLabel, progressBar
    });

        //// 窗体宽度和高度根据控件内容动态调整
        //Width = progressBar.Right + padding * 2;  // 调整窗体宽度
        //Height = progressBar.Bottom + padding * 2;  // 调整窗体高度，增加底部留白
        Width =340;  // 调整窗体宽度
        Height =170;  // 调整窗体高度，增加底部留白
    }



    // 创建托盘图标
    private void CreateTrayIcon()
    {
        trayIcon = new NotifyIcon
        {
            Icon = new Icon("app.ico"), // 确保项目中有一个图标文件
            Visible = true,
            ContextMenu = new ContextMenu(new MenuItem[] {
                new MenuItem("显示", (s, e) => Show()),
                new MenuItem("退出", (s, e) => Application.Exit())
            })
        };

        // 处理窗口最小化事件
        Resize += (s, e) =>
        {
            if (WindowState == FormWindowState.Minimized)
            {
                Hide();
                trayIcon.ShowBalloonTip(1000, "MouseClickTool", "程序已最小化到托盘", ToolTipIcon.Info);
            }
        };
    }

    private void HotkeyComboBox_SelectedIndexChanged(object sender, EventArgs e)
    {
        startStopHotkey = (Keys)Enum.Parse(typeof(Keys), hotkeyComboBox.SelectedItem.ToString());
        RegisterHotKey(); // 重新注册快捷键
    }

    private void StartButtonClick(object sender, EventArgs e)
    {
        if (!clicker.IsRunning)
        {
            StartClicking(); // 开始点击
        }
        else
        {
            StopClicking(); // 停止点击
        }
    }

    private void StartClicking()
    {
        // 验证输入框中的内容
        if (int.TryParse(intervalTextBox.Text, out int interval) && interval > 0 &&
            int.TryParse(clickCountTextBox.Text, out int totalClicks) && totalClicks > 0)
        {
            MouseEventFlag downFlag = MouseEventFlag.MOUSEEVENTF_LEFTDOWN;
            MouseEventFlag upFlag = MouseEventFlag.MOUSEEVENTF_LEFTUP;

            if (buttonComboBox.SelectedIndex == 1) // 右键
            {
                downFlag = MouseEventFlag.MOUSEEVENTF_RIGHTDOWN;
                upFlag = MouseEventFlag.MOUSEEVENTF_RIGHTUP;
            }

            // 更新点击器配置并启动
            clicker.Update(totalClicks, interval, UpdateProgress);
            clicker.StartAsync(downFlag, upFlag);

            startButton.Text = "结束";
            intervalTextBox.Enabled = clickCountTextBox.Enabled = hotkeyComboBox.Enabled = buttonComboBox.Enabled = false;
        }
        else
        {
            MessageBox.Show("请输入有效的间隔和点击次数!", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
        }
    }

    private void StopClicking()
    {
        clicker.Stop(); // 停止点击
        startButton.Text = "开始";
        intervalTextBox.Enabled = clickCountTextBox.Enabled = hotkeyComboBox.Enabled = buttonComboBox.Enabled = true;
    }

    private void UpdateProgress(int currentClicks, int totalClicks)
    {
        // 更新进度条和标签
        Invoke(new Action(() =>
        {
            progressLabel.Text = $"进度: {currentClicks}/{totalClicks}";
            progressBar.Maximum = totalClicks;
            progressBar.Value = currentClicks;
        }));
    }

    private void RegisterHotKey()
    {
        // 注销之前的快捷键，注册新的快捷键
        UnregisterHotKey(Handle, hotkeyId);

        if (!RegisterHotKey(Handle, hotkeyId, 0, (uint)startStopHotkey))
        {
            MessageBox.Show("无法注册快捷键!", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
        }
    }

    protected override void WndProc(ref Message m)
    {
        const int WM_HOTKEY = 0x0312;
        if (m.Msg == WM_HOTKEY)
        {
            if (!clicker.IsRunning)
            {
                StartClicking(); // 如果没有运行，开始点击
            }
            else
            {
                StopClicking(); // 如果正在运行，停止点击
            }
        }
        base.WndProc(ref m);
    }

    [STAThread]
    public static void Main()
    {
        SetProcessDPIAware();
        Application.EnableVisualStyles();
        Application.Run(new MouseClickTool());
    }
}

// 鼠标点击器类，用于处理点击逻辑
public class MouseClicker
{
    private int totalClicks; // 总点击次数
    private int interval; // 点击间隔
    private int currentClicks; // 当前点击次数
    private CancellationTokenSource cts; // 取消任务的令牌
    private Action<int, int> progressCallback; // 进度回调

    public bool IsRunning { get; private set; } // 当前任务是否正在运行

    public MouseClicker(int totalClicks, int interval, Action<int, int> progressCallback)
    {
        this.totalClicks = totalClicks;
        this.interval = interval;
        this.progressCallback = progressCallback;
        IsRunning = false;
    }

    // 更新点击任务的参数
    public void Update(int totalClicks, int interval, Action<int, int> progressCallback)
    {
        this.totalClicks = totalClicks;
        this.interval = interval;
        this.progressCallback = progressCallback;
    }

    // 异步开始点击任务
    public async void StartAsync(MouseEventFlag downFlag, MouseEventFlag upFlag)
    {
        if (IsRunning)
            return;

        IsRunning = true;
        currentClicks = 0;
        cts = new CancellationTokenSource();

        var inputDown = new Input
        {
            type = 0,
            mkhi = new MouseKeybdHardwareInputUnion
            {
                mi = new MouseInput { dwFlags = downFlag }
            }
        };

        var inputUp = new Input
        {
            type = 0,
            mkhi = new MouseKeybdHardwareInputUnion
            {
                mi = new MouseInput { dwFlags = upFlag }
            }
        };

        int size = Marshal.SizeOf(inputDown);

        try
        {
            // 开始异步点击任务
            await Task.Run(async () =>
            {
                while (currentClicks < totalClicks && !cts.Token.IsCancellationRequested)
                {
                    SendInput(1, new[] { inputDown }, size); // 模拟鼠标按下
                    SendInput(1, new[] { inputUp }, size);   // 模拟鼠标抬起

                    currentClicks++;
                    progressCallback?.Invoke(currentClicks, totalClicks);

                    await Task.Delay(interval, cts.Token); // 延迟
                }
            });
        }
        catch (TaskCanceledException)
        {
            // 任务被取消时的处理
        }

        IsRunning = false;
        progressCallback?.Invoke(currentClicks, totalClicks); // 最后更新一次进度
    }

    // 停止点击任务
    public void Stop()
    {
        if (IsRunning)
        {
            cts.Cancel();
        }
    }

    // 模拟输入
    [DllImport("user32.dll")]
    private static extern uint SendInput(uint nInputs, Input[] pInputs, int cbSize);

    [StructLayout(LayoutKind.Sequential)]
    private struct Input
    {
        public int type;
        public MouseKeybdHardwareInputUnion mkhi;
    }

    [StructLayout(LayoutKind.Explicit)]
    private struct MouseKeybdHardwareInputUnion
    {
        [FieldOffset(0)] public MouseInput mi;
    }

    [Flags]
    public enum MouseEventFlag : uint
    {
        MOUSEEVENTF_LEFTDOWN = 0x0002,
        MOUSEEVENTF_LEFTUP = 0x0004,
        MOUSEEVENTF_RIGHTDOWN = 0x0008,
        MOUSEEVENTF_RIGHTUP = 0x0010,
    }

    [StructLayout(LayoutKind.Sequential)]
    public struct MouseInput
    {
        public int dx;
        public int dy;
        public uint mouseData;
        public MouseEventFlag dwFlags;
        public uint time;
        public IntPtr dwExtraInfo;
    }
}
